<?php
/**
 * @package    Joomla.Tutorials
 * @subpackage Components
 * @link http://docs.joomla.org/Developing_a_Model-View-Controller_Component_-_Part_1
 * @license    GNU/GPL
 */
 
// No direct access
 
defined( '_JEXEC' ) or die( 'Restricted access' );
 
jimport('joomla.application.component.controller');
jimport('joomla.application.environment.response');
jimport( 'joomla.application.component.view' );

require_once (JPATH_COMPONENT_SITE.DS."views/csmbol/tmpl/csmbol-global-conf.php");

/**
 * csmbol World Component Controller
 *
 * @package    Joomla.Tutorials
 * @subpackage Components
 */
class csmbolController extends JController
{
	//the dev/release switch
	static $release = true;
    /**
     * Method to display the view
     *
     * @access    public
     */
    function display()
    {
		parent::display();
    }
	function chkRegisteredUser(){
		$param["release"] = self::$release; 		
		$c =& csmbolGlobalConf::Instance($param);
		$rts["rts"] = $c->rts_success;
		$rts["rtmsg"] = $c->rtmsg_success;
		$rts["rtmsg_embeded_code"] = "";			
		
		$user_group = $this->getUserGroup();
		
		$jsondata = array("user_group"=>$user_group);

		echo $this->getJSON($jsondata);
		return;				
	}
	
	function iniBooking(){
		$param["release"] = self::$release; 		
		$c =& csmbolGlobalConf::Instance($param);
		$rts["rts"] = $c->rts_success;
		$rts["rtmsg"] = $c->rtmsg_success;
		$rts["rtmsg_embeded_code"] = "";	
		
		$current_room = JRequest::getVar('current_room');	
	
		$user_group = $this->getUserGroup();
		
		$session = JFactory::getSession();
		//get booking status
		$booking_status = $session->get('booking_status');
		if($booking_status !=  "payment_done"){
			$this->clearSessionStore();//clear booking entries info of the previous booking
			$booking_status = "client_in_progress";
			$session->set('booking_status', $booking_status);
		}
		//get the timebox code
		$bookingdata = array();					
		if(!$session->has('bookingdata')) {
			//html code of the first box 
			$filename_timebox = JPATH_COMPONENT_SITE.DS."views/csmbol/tmpl/resp_timebox.php";
			$handle = fopen($filename_timebox, "r");
			$bookingdata['timeboxcode'] = fread($handle, filesize($filename_timebox));
			fclose($handle);
			$session->set('bookingdata', $bookingdata);				
		}else{
			$bookingdata = $session->get('bookingdata');
		}
		//get booking rates		
		$rates = $this->getRates($current_room);//get booking rates array(associative);
		
		if($user_group['guest']){
			$rts["rts"] = $c->rts_error;
			$rts["rtmsg"] = /*$c->rtmsg_error.*/$c->wrapMsg("Verified event organizers, please login.","csmbol-msg-error");
			$rts["rtmsg_embeded_code"] = $c->rt_csinfo;				
		}
		
		$jsondata = array("room"=>$current_room,"rates" => $rates,"user_group"=>$user_group,'booking_status'=>$booking_status,'pp_return'=>$c->pp_return, 'pp_cancel'=>$c->pp_cancel);

		$jsondata["rts"] = $rts["rts"];
		$jsondata["rtmsg"] = $rts["rtmsg"];
		$jsondata["rtmsg_embeded_code"] = $rts["rtmsg_embeded_code"];	

		echo $this->getJSON($jsondata);
		return;
	}
	
	function getRates($current_room){
		$param["release"] = self::$release; 		
		$c =& csmbolGlobalConf::Instance($param);
				
		$rates = array();
		$rates = $c->rates;
		return $rates;
	}

	function checkSession(){
		$session_exists = true;
		$session = JFactory::getSession();
		if($session->isNew()){
			$session_exists = false;
			$session->clear();
		}
		echo $this->getJSON($session_exists);
        return;
	}
	
	function setBookingStatus($status){
		$session = JFactory::getSession();
		$session->set('booking_status', $status);		
	}	
	
	function chkBookingStatus(){
        return;	
	}
	
	//internal 
	function chkDayAvailabler($date, $current_room, $pslot_flag = '', $check_pending = true){
		$param["release"] = self::$release; 		
		$c =& csmbolGlobalConf::Instance($param);
		$jsondata["rts"] = $c->rts_success;
		$jsondata["rtmsg"] = $c->rtmsg_success;
		$jsondata["rtmsg_embeded_code"] = "";

//		$current_room = JRequest::getVar('current_room');	
		$booking_default_cal_user = $c->booking_cal_info[$current_room]["cal_user"];
		$booking_default_cal_magicCookie = $c->booking_cal_info[$current_room]["cal_mc"];		
		$booking_pending_cal_user  = $c->booking_cal_info[$current_room]["cal_pending_user"];			
		$cal_default_uri  = $c->booking_cal_info[$current_room]["cal_uri"];
		$cal_pending_uri = $c->booking_cal_info[$current_room]["cal_pending_uri"];
				
		date_default_timezone_set('Asia/Singapore');
		//need to get the next day for gcal query as it's upper-bound-exclusive
		//refer to http://code.google.com/apis/calendar/data/1.0/reference.html#Parameters
		$date2 = date('Y-m-d', strtotime('+1 days', strtotime($date)));

		//check defualt calendar for confirmed bookings	
		$gcal = $this->getGcal('read');	//when use 'read' without authentication, user and magic cookie must be specified
		$query = $gcal->newEventQuery();
		$query->setUser($booking_default_cal_user);
		$query->setVisibility('private-'.$booking_default_cal_magicCookie);
		$query->setProjection('full');
//		$query->setFutureevents('true'); //this line overrides setStartMin/Max, so must be removed
		$query->setStartMin($date);//also can, but ISO 8601 format not required: date("c",strtotime($date)));
		$query->setStartMax($date2);//also can, but ISO 8601 format not required: date("c",strtotime($date2)));
//		return date_default_timezone_get();//date("c",strtotime($date))." and ".date("c",strtotime($date2)); 

		$slot_am = "avail";
		$slot_pm = "avail";
		$slot_ev = "avail";
		$slot_fd1 = "avail";
		$slot_fd2 = "avail";
		$slot_cd = "avail";	
		
		try {
			$eventfeed = $gcal->getCalendarEventFeed($query);
			foreach($eventfeed as $event){
//	  			$ep = $event->getExtendedProperty();
//				if($ep){
//					$flag_slot = $ep[0]->getValue();
//					$flag_booking_status = $ep[1]->getValue();	
//				}else{
					$when = $event->getWhen();
					$flag_slot = $this->decideSlotFlag($when[0]->getStartTime(),$when[0]->getEndTime());	
//				}
				
				switch ($flag_slot){
					case "slot_am":
						$slot_am = "booked";
						break;
					case "slot_pm":
						$slot_pm = "booked";
						break;
					case "slot_ev":
						$slot_ev = "booked";
						break;
					case "slot_fd1":
						$slot_fd1 = "booked";
						$slot_am = "booked";
						$slot_pm = "booked";													
						break;
					case "slot_fd2":
						$slot_fd2 = "booked";
						$slot_pm = "booked";
						$slot_ev = "booked";													
						break;						
					case "slot_cd":
						$slot_cd = "booked";
						$slot_am = "booked";
						$slot_pm = "booked";
						$slot_ev = "booked";													
						break;				
					default:
						break;
				}																									
/**/		}
		} catch (Zend_Gdata_App_Exception $e) {
		//	echo "Error: " . $e->getMessage();
			$jsondata["rts"] = $c->rts_error;
			$jsondata["rtmsg"] = $c->rtmsg_error_cal_down."-confirmed cal";
			$jsondata["rtmsg_embeded_code"] = $c->rtmsg_embeded_code;//"Error: ".$e->getMessage();
		}
		
		$msg = "none";		
		
		if($check_pending){
			//check 'client_pending' calendar for pending bookings
			$gcal = $this->getGcal();//full access	
			$query = $gcal->newEventQuery();
			$query->setUser($booking_pending_cal_user); //accessing the pending cal
			$query->setVisibility('private');//not using magicCookie, so we can use full-access
			$query->setProjection('full');
			$query->setStartMin($date);
			$query->setStartMax($date2);
			try {
				$eventfeed = $gcal->getCalendarEventFeed($query);
				foreach($eventfeed as $event){//pending events
					$ep = $event->getExtendedProperty();
					if($ep){
						$flag_slot = $ep[1]->getValue();
						$flag_booking_status = $ep[2]->getValue();
						$flag_bpt = $ep[3]->getValue();
						$flag_bpcid = $ep[4]->getValue();
						$flag_amt = $ep[5]->getValue(); 				
					}else{
						$when = $event->getWhen();
						$flag_slot = $this->decideSlotFlag($when[0]->getStartTime(),$when[0]->getEndTime());
					}				
	/**/				
					$author = $event->getAuthor();//->text;//getAuthor();
					$event_creator = $author[0]->getEmail()->text; //getName() no longer returns email but the display name 20120507
					
					//$msg = $event_creator;
					
					$booking_status = "";
					if(($event_creator != "oliver-lu@csm.sg")
					 &&($event_creator != "olivia.shao@csm.sg")
					 &&(true/*$event_creator != "testcal@csm.sg"*/)
					 &&(true/*$event_creator != "csmbol.cal@csm.sg"*/)
					 &&(true/*$event_creator != "testcal@csm.sg"*/)){
						//pending event created by csmbol, not human
						$pending_sec = $this->getPendingSeconds($flag_amt,$c->client_pending_duration);
						$curTime = time();
						$user = & JFactory::getUser();		
						$booking_pending_client_id = $user->id;		
						
						if((($curTime-$flag_bpt)<$pending_sec)&&($flag_bpcid!=$booking_pending_client_id)){//check pending expiry
							//client pending in progress
							$booking_status = "client_pending";
						}else{//pending expired, delete pending event
							if(($pslot_flag=='')||($pslot_flag == $flag_slot)) //check ae scenario, if not then delete
							$event->delete();
						};
					}else{ //pending event created by human
						//admin pending in progress
						$booking_status = "admin_pending";
					}
					if(($booking_status=="client_pending")||($booking_status=="admin_pending")){
						switch ($flag_slot){
							case "slot_am":
								if($slot_am != "booked") $slot_am = $booking_status;
								break;
							case "slot_pm":
								if($slot_pm != "booked") $slot_pm = $booking_status;
								break;
							case "slot_ev":
								if($slot_ev != "booked") $slot_ev = $booking_status;
								break;
							case "slot_fd1":
								if($slot_fd1 != "booked") $slot_fd1 = $booking_status;
								if($slot_am != "booked") $slot_am = $booking_status;
								if($slot_pm != "booked") $slot_pm = $booking_status;													
								break;
							case "slot_fd2":
								if($slot_fd2 != "booked") $slot_fd2 = $booking_status;
								if($slot_pm != "booked") $slot_pm = $booking_status;
								if($slot_ev != "booked") $slot_ev = $booking_status;													
								break;						
							case "slot_cd":
								if($slot_cd != "booked") $slot_cd = $booking_status;
								if($slot_am != "booked") $slot_am = $booking_status;
								if($slot_pm != "booked") $slot_pm = $booking_status;
								if($slot_ev != "booked") $slot_ev = $booking_status;													
								break;				
							default:
								break;
						}
					}
				}
			} catch (Zend_Gdata_App_Exception $e) {
	//			echo "Error: " . $e->getMessage();
				$jsondata["rts"] = $c->rts_error;
				$jsondata["rtmsg"] = $c->rtmsg_error_cal_down."-pending cal";
				$jsondata["rtmsg_embeded_code"] = $c->rtmsg_embeded_code;
			}
		}
		
//		$jsondata["rtmsg_embeded_code"] = $msg;
		
		$result = $this->chkPublicHoliday($date);
		$ph = $result["slot_ph"];
		if($result["rtsdata"]["rts"]==$c->rts_error){
			$jsondata["rts"] = $result["rtsdata"]["rts"];
			$jsondata["rtmsg"] = $result["rtsdata"]["rtmsg"];
			$jsondata["rtmsg_embeded_code"] = $result["rtsdata"]["rtmsg_embeded_code"];	
		}
		$day_avail = array("rtsdata"=>$jsondata,"slot_am"=>$slot_am,"slot_pm"=>$slot_pm,"slot_ev"=>$slot_ev,"slot_fd1"=>$slot_fd1,"slot_fd2"=>$slot_fd2,"slot_cd"=>$slot_cd, "ph"=>$ph/*, "chkpending"=>$chkpending*/);		
		return $day_avail;			
	}
	function chkPublicHoliday($date){
		$param["release"] = self::$release; 		
		$c =& csmbolGlobalConf::Instance($param);
		$jsondata["rts"] = $c->rts_success;
		$jsondata["rtmsg"] = $c->rtmsg_success;
		$jsondata["rtmsg_embeded_code"] = "";		
				
		date_default_timezone_set('Asia/Singapore');
		//need to get the next day for gcal query as it's upper-bound-exclusive
		//refer to http://code.google.com/apis/calendar/data/1.0/reference.html#Parameters
		$date2 = date('Y-m-d', strtotime('+1 days', strtotime($date)));

		//check defualt calendar for confirmed bookings	
		$gcal = $this->getGcal();//full access, works even when cal setting is set to 'show busy/free only', which getGcal('read') won't work
		$query = $gcal->newEventQuery();
		$query->setUser($c->ph_cal_sg_user_csm); //accessing the pending cal
		$query->setVisibility('private');//not using magicCookie, so we can use full-access
		$query->setProjection('full');
		$query->setStartMin($date);//also can, but ISO 8601 format not required: date("c",strtotime($date)));
		$query->setStartMax($date2);//also can, but ISO 8601 format not required: date("c",strtotime($date2)));

		$slot_ph = "none";
		try {
			$eventfeed = $gcal->getCalendarEventFeed($query);
			foreach($eventfeed as $event){
				$slot_ph = $event->title->text;																
			}
		} catch (Zend_Gdata_App_Exception $e) {
//			echo "Error: " . $e->getMessage();
			$jsondata["rts"] = $c->rts_error;
			$jsondata["rtmsg"] = $c->rtmsg_error_cal_down."-PH";
			$jsondata["rtmsg_embeded_code"] = $c->rtmsg_embeded_code;
		}

		return $result = array("rtsdata"=>$jsondata,"slot_ph"=>$slot_ph);			
	}
	function getPendingSeconds($amt, $cpd){
		//<=$120: 5min; <=$240: 8min; <=$600: 10min; >600: 15min
		$step1 = 120;
		$step2 = 240;
		$step3 = 600;
		$expiry_setter = 8;
		if(($amt>$step1)&&($amt<=$step2)) $expiry_setter = 10;
		else if(($amt>$step2)&&($amt<=$step3)) $expiry_setter = 12;
			else if($amt>$step3) $expiry_setter = 15;
		return $cpd*$expiry_setter;
	}	
	function updateTimeBox(){
		$param["release"] = self::$release; 		
		$c =& csmbolGlobalConf::Instance($param);	
		$rts["rts"] = $c->rts_success;
		$rts["rtmsg"] = $c->rtmsg_success;
		$rts["rtmsg_embeded_code"] = "";	
				
		$current_room = JRequest::getVar('current_room');
		$date = JRequest::getVar('date');
		$day_avail = $this->chkDayAvailabler($date, $current_room);	
//		echo $day_avail["rtsdata"]["rtmsg_embeded_code"]; return;

		$user_group = $this->getUserGroup();		
		if($user_group['guest']){
			$rts["rts"] = $c->rts_error;
			$rts["rtmsg"] = $c->rtmsg_error.$c->wrapMsg("Probably because you have logged out. Please re-login.","csmbol-msg-error");
			$rts["rtmsg_embeded_code"] = $c->rt_csinfo;				
		}else{				
			$session = JFactory::getSession();	
			if($session->has('bookingdata')){	
				$bookingdata = $session->get('bookingdata');
			}else{//session data lost, probably due to user logout
				$rts["rts"] = $c->rts_error;
				$rts["rtmsg"] = $c->rtmsg_error.$c->wrapMsg("Probably because you have logged out. Please re-login.","csmbol-msg-error");
				$rts["rtmsg_embeded_code"] = "";			
			}
		}
		$box_number = JRequest::getVar('box_number');
		$id = $box_number; //box_number passed by request
		
		$tmp = str_replace("CAL_INFO_D", $calcode, $bookingdata['timeboxcode']);							
		$tmp2 = str_replace("SLOT_AM_D", "slot_am_".$id, $tmp);
		$tmp3 = str_replace("SLOT_PM_D", "slot_pm_".$id, $tmp2);	
		$tmp4 = str_replace("SLOT_EV_D", "slot_ev_".$id, $tmp3);	
		$tmp5 = str_replace("SLOT_FC_D", "slot_fc_".$id, $tmp4);
//		$tmp6 = str_replace("BOX_NUM_D", $id, $tmp5); 									
		$data = str_replace(">BOX_ID_D", " id=\"box_id_".$id."\">#".$id, $tmp5);
		//BL:admin pending display as client pending
		if($day_avail["slot_am"]=="admin_pending") $day_avail["slot_am"]="client_pending";
		if($day_avail["slot_pm"]=="admin_pending") $day_avail["slot_pm"]="client_pending";		
		if($day_avail["slot_ev"]=="admin_pending") $day_avail["slot_ev"]="client_pending";		
		if($day_avail["slot_fd1"]=="admin_pending") $day_avail["slot_fd1"]="client_pending";		
		if($day_avail["slot_fd2"]=="admin_pending") $day_avail["slot_fd2"]="client_pending";			
		if($day_avail["slot_cd"]=="admin_pending") $day_avail["slot_cd"]="client_pending";				
/**/		
		$jsondata = array("htmlcode" => $data, "id" => $id, "slot_am"=>$day_avail["slot_am"],"slot_pm"=>$day_avail["slot_pm"],"slot_ev"=>$day_avail["slot_ev"],"slot_fd1"=>$day_avail["slot_fd1"],"slot_fd2"=>$day_avail["slot_fd2"],"slot_cd"=>$day_avail["slot_cd"],"ph"=>$day_avail["ph"]);
		
		$jsondata["rts"] = $rts["rts"];
		$jsondata["rtmsg"] = $rts["rtmsg"];
		$jsondata["rtmsg_embeded_code"] = $rts["rtmsg_embeded_code"];	
				
		echo $this->getJSON($jsondata);
		return;
	}
	
	function makeBooking($booking_type="confirmed"){
		$param["release"] = self::$release; 		
		$c =& csmbolGlobalConf::Instance($param);	
		$jsondata["rts"] = $c->rts_success;
		$jsondata["rtmsg"] = $c->rtmsg_success;
		$jsondata["rtmsg_embeded_code"] = "";	
		$error_stop = false;
		
		$booking_user = JRequest::getVar('user');
		$client_name = "";		
		$client_email = "";
		$client_phone = "";		
		$client_company = "";
		if($booking_user == "admin"){
			$client_name = JRequest::getVar('client_name');		
			$client_email = JRequest::getVar('client_email');		
			$client_phone = JRequest::getVar('client_phone');			
			$client_company = JRequest::getVar('client_company');									
		}
//		$entries_info = json_decode(JRequest::getVar('booking_entries'));
		$session = JFactory::getSession();
		$entries_info = json_decode($session->get('entries_info_json'));
		
		$booking_pending_timestamp = time();
		$user = & JFactory::getUser();		
		$booking_pending_client_id = $user->id;		
		
		$noe = count($entries_info) - $c->noae;
		$booking_desc = "";
		$place_holder = "";
		
		$booking_amt = $entries_info[$noe];/*array index issue*/
		$booking_number = $entries_info[$noe+1];
		$booking_add_msg = $entries_info[$noe+2];
		$client_phone = $entries_info[$noe+3];
		
		$booking_add_msg_proper = str_replace("%CR","<br>",$booking_add_msg);
		
		$chkpending = array();	
		$session_result = array();
		
		$msg1= "msg1";
		
		for($i=0; $i<$noe; $i++){
			//get confirmed event entry info
			$date = $entries_info[$i]->date;
			$date2 = date('Y-m-d', strtotime('+1 days', strtotime($date)));
			$title = $entries_info[$i]->title;
			$starttime =  $entries_info[$i]->starttime;
			$endtime =  $entries_info[$i]->endtime;		
			$event_room = $entries_info[$i]->event_room;	
			$slot_flag = $entries_info[$i]->slot_flag;			
			$booking_status = $entries_info[$i]->booking_status;	
	
			$msg1 = $slot_flag;
	
			switch ($event_room){
				case "action_room":
				$room_title = "Action Room";
				break;
				case "passion_room":
				$room_title = "Passion Room";
				break;
				case "genius_room":
				$room_title = "Genius Room";
				break;				
				case "elite_room":
				$room_title = "Elite Room";
				break;
				case "focus_room":
				$room_title = "Focus Room";
				break;				
				case "wisdom_room":
				$room_title = "Wisdom Room";
				break;
				case "harmony_room":
				$room_title = "Harmony Room";				
				break;
				case "spirit_room":
				$room_title = "Spirit Room";
				break;																		
			}
		
			$current_room = $event_room;	
			$booking_pending_cal_user  = $c->booking_cal_info[$current_room]["cal_pending_user"];			
			$cal_default_uri  = $c->booking_cal_info[$current_room]["cal_uri"];
			$cal_pending_uri = $c->booking_cal_info[$current_room]["cal_pending_uri"];
			
			if ($booking_type == "client_pending"){
//				$day_avail = $this->chkDayAvailabler($date, $current_room, $slot_flag, false);		
//the above function causes problem of multiple time slots booking of 6-8 and above
//				if($day_avail["rtsdata"]["rts"]==$c->rts_error) $error_stop = true;
//				$chkpending = $day_avail;
		
				if(true/*$day_avail[$slot_flag]=='avail'*/){	
					$gcal = $this->getGcal();
					$event = $gcal->newEventEntry();          
					$event->title = $gcal->newTitle($title);        
					$when = $gcal->newWhen();
					$when->startTime = $date."T".$starttime.":00";
					$when->endTime = $date."T".$endtime.":00";
					$event->when = array($when);        
					$noo = count($entries_info[$i]->entry_options);
					$opt_desc = "=>BID:".$booking_number."\n";
					$opt_desc .="=>On Duty:\n";
					$opt_desc .="=>Options:\n";					
					for($j=0;$j<$noo;$j++){
						if($entries_info[$i]->entry_options_number[$j]!=0)
							$opt_desc .= $entries_info[$i]->entry_options_number[$j]."x ".$entries_info[$i]->entry_options[$j]."\n";															
					}
					$opt_desc .="=>Additional Message:\n";
					$addmsg_proper = str_replace("%CR", chr(13), $entries_info[$noe+$c->noae-2]);/*array index issue*/ // -1 change to -2
					$opt_desc .= $addmsg_proper;//addtional message
                    $event->content = $gcal->newContent($opt_desc);
					$csmbolinfo = array();
					//Name/Value pair must be both set, otherwise the flag will not store as extended property
					$flag_slot = new Zend_Gdata_Extension_ExtendedProperty();		
					$flag_slot->setName('flag_slot');
					$flag_slot->setValue($slot_flag);$csmbolinfo[] = $flag_slot;
					$flag_bs = new Zend_Gdata_Extension_ExtendedProperty();	
					$flag_bs->setName('flag_booking_status');
					$flag_bs->setValue($booking_status);$csmbolinfo[] = $flag_bs;		
					$flag_bpt = new Zend_Gdata_Extension_ExtendedProperty();	
					$flag_bpt->setName('flag_bpt');
					$flag_bpt->setValue($booking_pending_timestamp);$csmbolinfo[] = $flag_bpt;	
					$flag_bpcid = new Zend_Gdata_Extension_ExtendedProperty();	
					$flag_bpcid->setName('flag_bpcid');
					$flag_bpcid->setValue($booking_pending_client_id);$csmbolinfo[] = $flag_bpcid;	
					$flag_amt = new Zend_Gdata_Extension_ExtendedProperty();	
					$flag_amt->setName('flag_amt');								
					$flag_amt->setValue($booking_amt);$csmbolinfo[] = $flag_amt;	
					$flag_bid = new Zend_Gdata_Extension_ExtendedProperty();	
					$flag_bid->setName('flag_bid');
					$flag_bid->setValue($booking_number);$csmbolinfo[] = $flag_bid;					
									
					$event->setExtendedProperty($csmbolinfo);
					try {
						$cal_uri = $cal_pending_uri;//"http://www.google.com/calendar/feeds/"."csm.sg_f8c3rt64fovfdq18nb6o5ch2ms@group.calendar.google.com"."/private/full";
						$gcal->insertEvent($event, $cal_uri);
						$session_result[] = "block_success";
					}catch (Zend_Gdata_App_Exception $e) {
//						echo "Error: " . $e->getMessage();
						$jsondata["rts"] = $c->rts_error;
						$jsondata["rtmsg"] = $c->rtmsg_error_cal_down;
						$jsondata["rtmsg_embeded_code"] = $c->rtmsg_embeded_code;
						//$error_stop = true; error when creating pending sessions, still proceed to send email
					}
				}else{//slot is pending or booked
					$session_result[] = $day_avail[$slot_flag];					
				}
			}else{//confirmed
				//get pending event for matching
				$gcal = $this->getGcal();//authenticated access for full access	
				$query = $gcal->newEventQuery();
				$query->setUser($booking_pending_cal_user);//if set to 'default' will only access the default calendar, now to access the pending cal
				$query->setVisibility('private');//if use MagicCookie(private-xxx) authentication, will give you read-only access
				$query->setProjection('full');//if 'basic', no 'when' will be retrived
				$query->setStartMin($date);
				$query->setStartMax($date2);
				$msg = "test";
				try {
					$eventfeed = $gcal->getCalendarEventFeed($query);//retrive the corresponding events in the pending cal
					foreach($eventfeed as $event_pending){
						$msg = "feed";
						$ep = $event_pending->getExtendedProperty();
						$pending_event_flag_slot = $ep[1]->getValue(); /*array index issue*/ //use to be $ep[0], seems array[] = element now starts from 1
						$msg = $pending_event_flag_slot;
						if($pending_event_flag_slot == $slot_flag){//matching pending event with event to be confirmed
							$msg = "flag";
							$event_confirmed = $gcal->newEventEntry();
							$event_confirmed->title = $event_pending->title;     
							$when = $gcal->newWhen();
							$when_pending = $event_pending->getWhen();
							$when->startTime = $when_pending[0]->getStartTime();
							$when->endTime = $when_pending[0]->getEndTime();	
							$event_confirmed->when = array($when); 						   
		                    $event_confirmed->content = $event_pending->content;
							$event_confirmed->setExtendedProperty($event_pending->getExtendedProperty());
							$event_pending->delete();							
							try {
								$cal_uri = $cal_default_uri;
								$gcal->insertEvent($event_confirmed,$cal_uri);//insert event into the defualt cal
							} catch (Zend_Gdata_App_Exception $e) {
//								echo "Error: " . $e->getResponse(); return;
								$jsondata["rts"] = $c->rts_error;
								$jsondata["rtmsg"] = $c->rtmsg_error_cal_down;
								$jsondata["rtmsg_embeded_code"] = $c->rtmsg_embeded_code;
								$error_stop = true;
							}
							break;
						}
					}
				} catch (Zend_Gdata_App_Exception $e) {
//					echo "Error: " . $e->getMessage();
					$jsondata["rts"] = $c->rts_error;
					$jsondata["rtmsg"] = $c->rtmsg_error_cal_down;
					$jsondata["rtmsg_embeded_code"] = $c->rtmsg_embeded_code;
					$error_stop = true;
				}					
			}
			
			if($booking_type == "confirmed"){
				//restore system state after booking is done
				$this->clearDates();
			}
			//gen desc for invoice
			$booking_desc .= "<div><strong>Session #".($i+1).": ".$date." ".$starttime."-".$endtime." ".$room_title."</strong></div>";
			$noo = count($entries_info[$i]->entry_options);
			$lead = "options: ";
			for($j=0;$j<$noo;$j++){
				if($entries_info[$i]->entry_options_number[$j] != 0){
					$booking_desc .= "<div>".$lead.$entries_info[$i]->entry_options_number[$j]."x ".$entries_info[$i]->entry_options[$j]."</div>";	
					$place_holder .= "<div>&nbsp;</div>";
				}
				if($j==0) $lead = "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;";				
			}
			if ($i<($noe-1)) $place_holder .= "<div>&nbsp;</div>";	
		}
		
		if(!$error_stop){
			$booking_client = "Client";	
	//		if($booking_type == "confirmed"){
			//if bookings are confirmed then do email invoice stuff
			if($booking_user == "admin"){//bracket is required becoz 'else' is following the nearest 'if'.
				if($client_name != "")
					$booking_client = $client_name;
			}else{
				$user = & JFactory::getUser();		
				$booking_client = $user->name;
			};
			$sum_amt = $entries_info[$noe];
			$total_amt = $sum_amt;
	//			$booking_number = $entries_info[$noe+1];
			date_default_timezone_set('Asia/Singapore');		
			$booking_date = date('Y-m-d');
			$billing_info = $booking_client.'<br>'.$client_company.'<br>'.$client_phone;
			$invoice_html = $this->genInvoice($booking_client, $booking_number, $booking_date, $billing_info, $room_title, $booking_desc, $sum_amt, $total_amt, $place_holder, $booking_add_msg_proper);

			if($booking_type == "confirmed"){
				$email_title = "Your booking is successful";
				$confirmed = true;
			}else{
				$email_title = "An user has made a pending booking";
				$confirmed = false;
			}
			$result = $this->sendNotificationEmails($invoice_html, $client_email, $client_phone, $email_title, $confirmed);
		}//if(!$error_stop)
			
		if($result["rtsdata"]["rts"]==$c->rts_error){
			$jsondata["rts"] = $result["rtsdata"]["rts"];
			$jsondata["rtmsg"] = $result["rtsdata"]["rtmsg"];
			$jsondata["rtmsg_embeded_code"] = $result["rtsdata"]["rtmsg_embeded_code"];	
		}
			
		$entries_info["rts"] = $jsondata["rts"];
		$entries_info["rtmsg"] = $jsondata["rtmsg"];
		$entries_info["rtmsg_embeded_code"] = $jsondata["rtmsg_embeded_code"];//$msg."---".$msg1;						
		if($booking_type == "confirmed"){
			echo $this->getJSON($entries_info);	
		}

		$session_result["rtsdata"] = $jsondata;
		return $session_result;//$chkpending;
	}
	
	function genInvoice($booking_client, $booking_number, $booking_date, $billing_info, $room_title, $booking_desc, $sum_amt,$total_amt, $place_holder, $booking_add_msg){

		$filename_email = JPATH_COMPONENT_SITE.DS."views/csmbol/tmpl/email.php";

		$handle = fopen($filename_email, "r");
		$data = fread($handle, filesize($filename_email));
		fclose($handle);
	
		$data2 = str_replace("BOOKING_CLIENT", $booking_client, $data);
		$data3 = str_replace("BOOKING_NUMBER", $booking_number, $data2);
		$data4 = str_replace("BOOKING_DATE", $booking_date, $data3);
		$data5 = str_replace("BILLING_INFO", $billing_info, $data4);		
		$data6 = str_replace("BOOKING_DESC", $booking_desc, $data5);
		$data7 = str_replace("BOOKING_AMT", $sum_amt.$place_holder, $data6);
		$data8 = str_replace("BOOKING_TOTAL", $total_amt, $data7);
		//$data9 = str_replace("ROOM_TITLE", $room_title, $data8);		
		$body = str_replace("BOOKING_ADD_MSG", $booking_add_msg, $data8);		
						
		return $body;	
	}
	
	function sendNotificationEmails($body_html, $email_add, $client_phone, $email_title, $confirmed){
		$param["release"] = self::$release; 		
		$c =& csmbolGlobalConf::Instance($param);
		$jsondata["rts"] = $c->rts_success;
		$jsondata["rtmsg"] = $c->rtmsg_success;
		$jsondata["rtmsg_embeded_code"] = "";		
		
		$mailer =& JFactory::getMailer();
		$config =& JFactory::getConfig();
		$sender = array( 'booking@csm.sg', 'CSM Facility Booking');
//		$config->getValue( 'config.mailfrom' ),
//		$config->getValue( 'config.fromname' ) );

		$user =& JFactory::getUser();
		$recipient_client = $user->email;
		$recipients = array();
		if(($recipient_client != "") && $confirmed) $recipients[] = $recipient_client;
		$recipients[] = 'oliver-lu@csm.sg';
		
/*		if(self::$release)
			$recipients[] = 'olivia.shao@csm.sg';
*/			
		if($email_add!="") $recipients[] = $email_add;
		
	 	$mailer->addRecipient($recipients);		
		$mailer->setSender($sender);	
		$mailer->setSubject($email_title);
		$mailer->isHTML(true);
		$mailer->setBody($body_html);	
		// Optional file attached
//		$mailer->addAttachment(JPATH_COMPONENT.DS.'assets'.DS.'document.pdf');
		// Take care of reply email addresses
/*		$replyto = "booking@csm.sg";
		$replytoname = "CSM Facility Booking";
		if (is_array($replyto)) {
				$numReplyTo = count($replyto);
				for ($i=0; $i < $numReplyTo; $i++){
					$mailer->addReplyTo(array($replyto[$i], $replytoname[$i]));
				}
		} elseif (isset($replyto)) {
	      		$mailer->addReplyTo(array($replyto, $replytoname));
		}
*/		
		$send =& $mailer->Send();
		
		if ( $send != true ) {
			$jsondata["rts"] = $c->rts_error;
			$jsondata["rtmsg"] = $c->rtmsg_error_send_email.$c->rt_csinfo;
			$jsondata["rtmsg_embeded_code"] = $c->rtmsg_embeded_code;
		} else {
//			echo 'Mail sent';
		}

		return $result = array("rtsdata"=>$jsondata);		
	}
	
	function readyEntriesForBooking(){
		$param["release"] = self::$release; 		
		$c =& csmbolGlobalConf::Instance($param);	
		
/*		the follwoing code is commented out due to Concurrent Requests for Session Access problem, where
		several requests make concurrent visit and may or may not find 'number_of_entries' in the sessoin store
		and therefore will result in unpredictible results.
		if($session->has('number_of_entries'))
			$noe = $session->get('number_of_entries');
		else $noe = 0;
*/	
		//this will correctly decode json date back into the 2-d array passed from javascript
		//$entries_info[x][y] can be used.
		//but since we are putting the json data into session store, so no need to decode at this moment
//		$entries_info = json_decode(JRequest::getVar('booking_entries')); 	

		$entries_info_json = JRequest::getVar('booking_entries');
		
		//replace line break for json_decode to work properly
		$entries_info_json_proper = str_replace(chr(10), "%CR", $entries_info_json);
//		$entries_info_json_proper = str_replace(chr(13), "%LF", $entries_info_json_proper);	
//		$entries_info_json_proper = $this->convert_smart_quotes($entries_info_json_proper0);	
//		echo $entries_info_json_proper;
//		return;
		$session = JFactory::getSession();		
		$session->set('entries_info_json', $entries_info_json_proper);
		
		$entries_info = json_decode($entries_info_json_proper);
//		echo $entries_info;
//		return;
		
		$noe = count($entries_info)-$c->noae;
		$amt = $entries_info[$noe];
		$amt = str_replace("SGD","", $amt); 
		
		$session_result = $this->makeBooking("client_pending");

		$jsondata = array("htmlcode" => "ready", "noe"=>$noe, "pending_sec" => $this->getPendingSeconds((float)$amt, $c->client_pending_duration), "session_result"=>$session_result);
		$jsondata["rts"] = $session_result["rtsdata"]["rts"];
		$jsondata["rtmsg"] = $session_result["rtsdata"]["rtmsg"];
		$jsondata["rtmsg_embeded_code"] = $c->rtmsg_embeded_code;		
	   	echo $this->getJSON($jsondata);		
		
		return;
	}
	
	function convert_smart_quotes($string){ 
		$replace = array(chr(145), 
						chr(146), 
						chr(147), 
						chr(148), 
						chr(151)); 
	
		$search = array("'", 
						 "'", 
						 '"', 
						 '"', 
						 '-'); 
	
		return str_replace($search, $replace, $string); 
	} 
	
	function getBookingEntries(){
		$param["release"] = self::$release; 		
		$c =& csmbolGlobalConf::Instance($param);	
		$rts["rts"] = $c->rts_success;
		$rts["rtmsg"] = $c->rtmsg_success;
		$rts["rtmsg_embeded_code"] = "";	
				
		$session = JFactory::getSession();
		if($session->has('entries_info_json')){	
			$entries_info_json = $session->get('entries_info_json');
		}else{//session data lost, probably due to user logout
			$rts["rts"] = $c->rts_error;
			$rts["rtmsg"] = $c->rtmsg_error.$c->wrapMsg("Probably because you have logged out during the booking session." ,"csmbol-msg-error");
			$rts["rtmsg_embeded_code"] = $c->rt_csinfo;			
		}		
		
		$json_data = array("entries_info_json"=>json_decode($entries_info_json));
/**/	$json_data["rts"] = $rts["rts"];
		$json_data["rtmsg"] = $rts["rtmsg"];
		$json_data["rtmsg_embeded_code"] = $rts["rtmsg_embeded_code"];	
						
		echo $this->getJSON($json_data);	
				
		return;		
	}
	//with PayPal PDT configured, the single returning point
	//from PayPal is here, cancel or fail or success
	function checkReturn(){
		$param["release"] = self::$release; 		
		$c =& csmbolGlobalConf::Instance($param);		
// read the post from PayPal system and add 'cmd'
		$req = 'cmd=_notify-synch';
//		$tx_token = $_GET['tx'];
		$tx_token = JRequest::getVar('tx');	
		
		$auth_token = "2rsom4SkgZCdhNjzC1YpWIDzfW0__PL8zbECImZPB4OXv2SRj7xYTxY9iau";
		$req .= "&tx=$tx_token&at=$auth_token";
		// post back to PayPal system to validate
		$header .= "POST /cgi-bin/webscr HTTP/1.0\r\n";
		$header .= "Content-Type: application/x-www-form-urlencoded\r\n";
		$header .= "Content-Length: " . strlen($req) . "\r\n\r\n";
		$fp = fsockopen ('www.paypal.com', 80, $errno, $errstr, 30);
		// If possible, securely post back to paypal using HTTPS
		// Your PHP server will need to be SSL enabled
		// $fp = fsockopen ('ssl://www.paypal.com', 443, $errno, $errstr, 30);
		if (!$fp) {
		// HTTP ERROR
		} else {
			fputs ($fp, $header . $req);
			// read the body data
			$res = '';
			$headerdone = false;
			while (!feof($fp)) {
			$line = fgets ($fp, 1024);
		if (strcmp($line, "\r\n") == 0) {
			// read the header
			$headerdone = true;
		}
		else if ($headerdone)
		{
		// header has been read. now read the contents
			$res .= $line;
		}
		}
		
		// parse the data
		$lines = explode("\n", $res);
		$keyarray = array();
		if (strcmp ($lines[0], "SUCCESS") == 0) {
			for ($i=1; $i<count($lines);$i++){
				list($key,$val) = explode("=", $lines[$i]);
				$keyarray[urldecode($key)] = urldecode($val);
			}
			// check the payment_status is Completed
			// check that txn_id has not been previously processed
			// check that receiver_email is your Primary PayPal email
			// check that payment_amount/payment_currency are correct
			// process payment
/*			$firstname = $keyarray['first_name'];
			$lastname = $keyarray['last_name'];
			$itemname = $keyarray['item_name'];
			$amount = $keyarray['mc_gross'];
			
			echo ("<p><h3>Thank you for your purchase!</h3></p>");
			
			echo ("<b>Payment Details</b><br>\n");
			echo ("<li>Name: $firstname $lastname</li>\n");
			echo ("<li>Item: $itemname</li>\n");
			echo ("<li>Amount: $amount</li>\n");
			echo ("");
*/			
			$session = JFactory::getSession();
			$session->set('booking_status', 'payment_done');								

		}else if (strcmp ($lines[0], "FAIL") == 0) {
		// log for manual investigation
		}
		}
		fclose ($fp);
		
//		echo "Your transaction has been completed, and a receipt for your purchase has been emailed to you.<br>You may log into your account at <a href='https://www.paypal.com'>www.paypal.com</a> to view details of this transaction.<br>";		
//        parent::display();	
		$this->setRedirect( $c->com_url);
	}

	function checkIPNReturn_MMI(){
		$param["release"] = self::$release; 		
		$c =& csmbolGlobalConf::Instance($param);		

		error_reporting(E_ALL ^ E_NOTICE);

		// Read the post from PayPal and add 'cmd'
		$req = 'cmd=_notify-validate';
		if(function_exists('get_magic_quotes_gpc')){
			$get_magic_quotes_exits = true;
		}
		foreach ($_POST as $key => $value)
		// Handle escape characters, which depends on setting of magic quotes
		{
			if($get_magic_quotes_exists == true && get_magic_quotes_gpc() == 1){
				$value = urlencode(stripslashes($value));
			} else {
				$value = urlencode($value);
			}
			$req .= "&$key=$value";
		}
		// Post back to PayPal to validate
		$header .= "POST /cgi-bin/webscr HTTP/1.0\r\n";
		$header .= "Content-Type: application/x-www-form-urlencoded\r\n";
		$header .= "Content-Length: " . strlen($req) . "\r\n\r\n";
		$fp = fsockopen ('ssl://www.paypal.com', 443, $errno, $errstr, 30);
		// Process validation from PayPal
		// TODO: This sample does not test the HTTP response code. All
		// HTTP response codes must be handles or you should use an HTTP
		// library, such as cUrl
		if (!$fp) { // HTTP ERROR
		} 
		else {
		// NO HTTP ERROR
			fputs ($fp, $header . $req);
			while (!feof($fp)) {
				$res = fgets ($fp, 1024);
				
				$mailer =& JFactory::getMailer();
				$recipient_client = $_POST['payer_email'];
				$client_name = $_POST['address_name'];
				$contact_phone = $_POST['contact_phone'];				
				$txn_id = $_POST['txn_id'];
								
				$recipients = array();
				if($recipient_client != "") $recipients[] = $recipient_client;
				$recipients[] = 'oliver-lu@csm.sg';
				
				$filename_timebox = JPATH_COMPONENT_SITE.DS."views/csmbol/tmpl/mmi_confirmation.html";
				$handle = fopen($filename_timebox, "r");
				$mmi_confirmation = fread($handle, filesize($filename_timebox));
				fclose($handle);

				$tmp = str_replace("MMI_NAME", $client_name, $mmi_confirmation);							
				$tmp2 = str_replace("MMI_EMAIL", $recipient_client, $tmp);
				$tmp3 = str_replace("MMI_HP", $contact_phone, $tmp2);	
				$mmi_confirmation = str_replace("MMI_REF", $txn_id, $tmp3);	

				$body_html = $mmi_confirmation;
				$email_title = "Your Millionaire Mind Intensive VIP Registration is Confirmed!";
				$sender = array( 'reg@csm.sg', 'CSM Event Registration');		
		
				$mailer->addRecipient($recipients);		
				$mailer->setSender($sender);	
				$mailer->setSubject($email_title);
				$mailer->isHTML(true);
				$mailer->setBody($body_html);	
				// Optional file attached
				// $mailer->addAttachment(JPATH_COMPONENT.DS.'assets'.DS.'document.pdf');

				if (strcmp ($res, "VERIFIED") == 0) {
					// TODO:
					// Check the payment_status is Completed
					// Check that txn_id has not been previously processed
					// Check that receiver_email is your Primary PayPal email
					// Check that payment_amount/payment_currency are correct
					// Process payment
					// If 'VERIFIED', send an email of IPN variables and values to the
					// specified email address
					foreach ($_POST as $key => $value){
						$emailtext .= $key . " = " .$value ."\n\n";
					}
//					mail($email, "Live-VERIFIED IPN", $emailtext . "\n\n" . $req);
					$send =& $mailer->Send();
				} else if (strcmp ($res, "INVALID") == 0) {
					// If 'INVALID', send an email. TODO: Log for manual investigation.
//					foreach ($_POST as $key => $value){
//						$emailtext .= $key . " = " .$value ."\n\n";
//					}
//					mail($email, "Live-INVALID IPN", $emailtext . "\n\n" . $req);
//					$send =& $mailer->Send();
				}
			}
		}
		fclose ($fp);
	}	
	
	function checkIPNReturn_NAC_general(){
		$param["release"] = self::$release; 		
		$c =& csmbolGlobalConf::Instance($param);		

		error_reporting(E_ALL ^ E_NOTICE);

		// Read the post from PayPal and add 'cmd'
		$req = 'cmd=_notify-validate';
		if(function_exists('get_magic_quotes_gpc')){
			$get_magic_quotes_exits = true;
		}
		foreach ($_POST as $key => $value)
		// Handle escape characters, which depends on setting of magic quotes
		{
			if($get_magic_quotes_exists == true && get_magic_quotes_gpc() == 1){
				$value = urlencode(stripslashes($value));
			} else {
				$value = urlencode($value);
			}
			$req .= "&$key=$value";
		}
		// Post back to PayPal to validate
		$header .= "POST /cgi-bin/webscr HTTP/1.0\r\n";
		$header .= "Content-Type: application/x-www-form-urlencoded\r\n";
		$header .= "Content-Length: " . strlen($req) . "\r\n\r\n";
		$fp = fsockopen ('ssl://www.paypal.com', 443, $errno, $errstr, 30);
		// Process validation from PayPal
		// TODO: This sample does not test the HTTP response code. All
		// HTTP response codes must be handles or you should use an HTTP
		// library, such as cUrl
		if (!$fp) { // HTTP ERROR
		} 
		else {
		// NO HTTP ERROR
			fputs ($fp, $header . $req);
			while (!feof($fp)) {
				$res = fgets ($fp, 1024);
				
				$mailer =& JFactory::getMailer();
				$recipient_client = $_POST['payer_email'];
				$client_name = $_POST['address_name'];
				$contact_phone = $_POST['contact_phone'];				
				$txn_id = $_POST['txn_id'];
								
				$recipients = array();
				if($recipient_client != "") $recipients[] = $recipient_client;
				$recipients[] = 'oliver-lu@csm.sg';
				
				$filename_timebox = JPATH_COMPONENT_SITE.DS."views/csmbol/tmpl/nac_confirmation_general.html";
				$handle = fopen($filename_timebox, "r");
				$nac_confirmation = fread($handle, filesize($filename_timebox));
				fclose($handle);

				$tmp = str_replace("NAC_NAME", $client_name, $nac_confirmation);							
				$tmp2 = str_replace("NAC_EMAIL", $recipient_client, $tmp);
				$tmp3 = str_replace("NAC_HP", $contact_phone, $tmp2);	
				$nac_confirmation = str_replace("NAC_REF", $txn_id, $tmp3);	

				$body_html = $nac_confirmation;
				$email_title = "Your National Achievers Congress General Registration is Confirmed!";
				$sender = array( 'reg@csm.sg', 'CSM Event Registration');		
		
				$mailer->addRecipient($recipients);		
				$mailer->setSender($sender);	
				$mailer->setSubject($email_title);
				$mailer->isHTML(true);
				$mailer->setBody($body_html);	
				// Optional file attached
				// $mailer->addAttachment(JPATH_COMPONENT.DS.'assets'.DS.'document.pdf');

				if (strcmp ($res, "VERIFIED") == 0) {
					// TODO:
					// Check the payment_status is Completed
					// Check that txn_id has not been previously processed
					// Check that receiver_email is your Primary PayPal email
					// Check that payment_amount/payment_currency are correct
					// Process payment
					// If 'VERIFIED', send an email of IPN variables and values to the
					// specified email address
					foreach ($_POST as $key => $value){
						$emailtext .= $key . " = " .$value ."\n\n";
					}
//					mail($email, "Live-VERIFIED IPN", $emailtext . "\n\n" . $req);
					$send =& $mailer->Send();
				} else if (strcmp ($res, "INVALID") == 0) {
					// If 'INVALID', send an email. TODO: Log for manual investigation.
//					foreach ($_POST as $key => $value){
//						$emailtext .= $key . " = " .$value ."\n\n";
//					}
//					mail($email, "Live-INVALID IPN", $emailtext . "\n\n" . $req);
//					$send =& $mailer->Send();
				}
			}
		}
		fclose ($fp);
	}	
		
	function showCancel(){
		$param["release"] = self::$release; 		
		$c =& csmbolGlobalConf::Instance($param);	

		$this->releasePendings();
		
		$session = JFactory::getSession();
		$session->set('booking_status', 'client_in_progress');				
//        parent::display();		
		$this->setRedirect( $c->com_url);
	}
	function releasePendings(){
		$this->getGcal("full");
		
		$this->clearSessionStore();
	}
	function test(){
		$session = JFactory::getSession();
		$entries_info_json = $session->get('entries_info_json');
		echo $this->getJSON($entries_info_json,false);	
		return;				
	}
	function clearDates(){
		$this->clearSessionStore();
		$session = JFactory::getSession();
		$session->set('booking_status', "client_in_progress");						
		return;
	}
	function clearSessionStore(){
		$session = JFactory::getSession();
//		$session->clear('booking_status');
//		$session->clear('bookingdata');
		$session->clear('entries_info_json');
        return;
	}
	function getUserGroup(){
		$param["release"] = self::$release; 		
		$c =& csmbolGlobalConf::Instance($param);		
		//access check
		$is_registered_user = false;		
		$is_guest = false;
		$is_event_organizer = false;
		$is_csm_booking_admin = false;
		$is_admin = false;
		$is_manager = false;	
		$is_super_user = false;			
		
		$user = & JFactory::getUser();		
        if ($user->guest) {
            $is_guest = true;
        } else {
			$user_groups = JAccess::getGroupsByUser($user->get('id'));
			
			foreach($user_groups as $group){
				if($group == $c->registered_user_gid){
					$is_registered_user = true;
				}				
				if($group == $c->event_organizer_gid){
					$is_event_organizer = true;
				}
				if($group == $c->csm_booking_admin_gid){
					$is_csm_booking_admin = true;
				}
				if($group == $c->admin_gid){
					$is_admin = true;
				}
				if($group == $c->manager_gid){
					$is_manager = true;
				}
				if($group == $c->super_user_gid){
					$is_super_user = true;
				}																
			}		
		}
		$user_group = array();	
		$user_group['registered_user'] = $is_registered_user;			
		$user_group['guest'] = $is_guest;
		$user_group['event_organizer'] = $is_event_organizer;
		$user_group['csm_booking_admin'] = $is_csm_booking_admin;
		$user_group['admin'] = $is_admin;		
		$user_group['manager'] = $is_manager;
		$user_group['super_user'] = $is_super_user;	
		
		return $user_group;		
	}
	function getJSON($jsondata, $encode = true){
		if($encode)
		    $json = json_encode($jsondata);
		else $json = $jsondata;	
	    // Get the document object.
        $document =& JFactory::getDocument();
        // Set the MIME type for JSON output.
        $document->setMimeEncoding( 'application/json' );
        // Change the suggested filename.
        JResponse::setHeader( 'Content-Disposition', 'attachment; filename="'.'csmbol'.'.json"' );
        // Output the JSON data.		
		return $json;
	}
	
	function getGcal($access = 'full',$cal_user="",$cal_password="" ){
		$param["release"] = self::$release; 		
		$c =& csmbolGlobalConf::Instance($param);
		
		require_once 'Zend/Loader.php';
		Zend_Loader::loadClass('Zend_Gdata');
		Zend_Loader::loadClass('Zend_Gdata_ClientLogin');
		Zend_Loader::loadClass('Zend_Gdata_Calendar');
		Zend_Loader::loadClass('Zend_Http_Client');
		
		if($access == "full"){
			$gcal = Zend_Gdata_Calendar::AUTH_SERVICE_NAME;
			if($cal_user=="")
				$cal_user = $c->booking_default_cal_base_user;
			if($cal_password=="")	
				$cal_password = $c->booking_default_cal_base_password;
			$client = Zend_Gdata_ClientLogin::getHttpClient($cal_user, $cal_password, $gcal);
		}else $client = null;
		
		return $gcal = new Zend_Gdata_Calendar($client);		
	}
	function chkATLogin(){
		$param["release"] = self::$release; 		
		$c =& csmbolGlobalConf::Instance($param);	
		$at_name = JRequest::getVar('at_name');
		$at_password = JRequest::getVar('at_password');		

		$result = "at_login_fail";				
		if($at_password == $c->at_login[$at_name])
			$result = "at_login_success";
					
		$jsondata = array("result" => $result);
	   	echo $this->getJSON($jsondata);	
		return;					
	}
	function getCalImpBoxCode(){
		$session = JFactory::getSession();		
		//get the timebox code
		$calimpcode = "";	
		if(!$session->has('calimpcode')) {
			//html code of the first box 
			$filename_at_cal_imp = JPATH_COMPONENT_SITE.DS."views/csmbol/tmpl/resp_at_cal_imp.php";
			$handle = fopen($filename_at_cal_imp, "r");
			$calimpcode = fread($handle, filesize($filename_at_cal_imp));
			fclose($handle);
			$session->set('calimpcode', $calimpcode);				
		}else{
			$calimpcode = $session->get('calimpcode');
		}
		$user_group = $this->getUserGroup();
		$jsondata = array("htmlcode" => $calimpcode,"user_group"=>$user_group);
		echo $this->getJSON($jsondata);
		return;				
	}
	function getCalInfo(){
		$param["release"] = self::$release; 		
		$c =& csmbolGlobalConf::Instance($param);	
				
		$src_cal = JRequest::getVar('src_cal');		
		$des_cal = JRequest::getVar('des_cal');	
		$src_cal_pass = JRequest::getVar('src_cal_pass');		
		$des_cal_pass = JRequest::getVar('des_cal_pass');		
			
		$gcal_src = $this->getGcal('full',$src_cal,$src_cal_pass);	
		$calFeed_src = $gcal_src->getCalendarListFeed();
		$calcode_src =""; $index =0;
		$session = JFactory::getSession();
		foreach ($calFeed_src as $calendar) {
//			if($calendar->title->text != "Singapore Holidays")
				$calcode_src .=  '<option value='.$index.'>' . $calendar->title->text . '</option>';
				$session->set('id_src_'.$index, $calendar->id->text);
				$index++;
		}
		$gcal_des = $this->getGcal('full',$des_cal,$des_cal_pass);	
		$calFeed_des = $gcal_des->getCalendarListFeed();
		$calcode_des =""; $index =0;
		$session = JFactory::getSession();	
		foreach ($calFeed_des as $calendar) {
			if($calendar->title->text != "Singapore Holidays"){
				$calcode_des .=  '<option value='.$index.'>' . $calendar->title->text . '</option>';
				$session->set('id_des_'.$index, $calendar->id->text);
				$index++;					
			}
		}
		
		//appending the google sg ph cal title
//		$calcode_src .=  '<option value='.$index.'>' . 'Google Singapore Holiday' . '</option>';
//		$session->set('id_src_'.$index, $c->$ph_cal_sg_user);		
				
		$jsondata = array("htmlcode_src" => $calcode_src,"htmlcode_des" => $calcode_des);
		echo $this->getJSON($jsondata);
		return;			
	}
	function getCalSpan(){
		$sel_src = JRequest::getVar('sel_src');		
		$sel_des = JRequest::getVar('sel_des');	
		$session = JFactory::getSession();	
		$cal_id_src = $session->get('id_src_'.$sel_src);
		$cal_id_des = $session->get('id_des_'.$sel_des);

		$id_str = "http://www.google.com/calendar/feeds/default/";
		$cal_user_src = str_replace($id_str, "",$cal_id_src);
		$cal_user_des = str_replace($id_str, "",$cal_id_des);							

		$session = JFactory::getSession();	
		$session->set('cal_user_src', $cal_user_src);		
		$session->set('cal_user_des', $cal_user_des);			

		$date_epoch = date('Y-m-d', mktime(0,0,0,1,1,2011 )); //action room epoch
		$date_vision = date('Y-m-d', strtotime('+2 years', mktime(0,0,0,date("m"),date("d"),date("Y") )));//current +2 years	
//		$date_epoch = date('Y-m-d', mktime(0,0,0,5,29,2011 )); //action room epoch
//		$date_vision =	date('Y-m-d', strtotime('+1 days', strtotime($date_epoch)));	

		$span_second = strtotime($date_vision) - strtotime($date_epoch);
		$span_week = intval($span_second/604800);

		$session->set('date_start', $date_epoch);
		
		$jsondata = array("span_week" => $span_week, "date_start"=>$date_epoch);
		echo $this->getJSON($jsondata);
		return;		
	}
	
	function getCalSlots(){
		$year = JRequest::getVar('year');		
		$month = JRequest::getVar('month');			

		$session = JFactory::getSession();	
		$cal_id_src = $session->get('id_src_'.$sel_src);
		
		$text = "";
		$ar_slots = $this->getCalRoomSlots2('action_room', $year, $month);
		$pr_slots = $this->getCalRoomSlots2('passion_room', $year, $month);
		$gr_slots = $this->getCalRoomSlots2('genius_room', $year, $month);
		$er_slots = $this->getCalRoomSlots2('elite_room', $year, $month);
		$fr_slots = $this->getCalRoomSlots2('focus_room', $year, $month);		
		$wr_slots = $this->getCalRoomSlots2('wisdom_room', $year, $month);
		$vr_slots = $this->getCalRoomSlots2('harmony_room', $year, $month);
		$sr_slots = $this->getCalRoomSlots2('spirit_room', $year, $month);
//		$slots_sum = $ar_slots + $pr_slots + $gr_slots + $er_slots;
		
		$text .= "<div>Action Room: ".$ar_slots."</div>";
		$text .= "<div>Passion Room: ".$pr_slots."</div>";		
		$text .= "<div>Genius Room: ".$gr_slots."</div>";
		$text .= "<div>Elite Room: ".$er_slots."</div>";	
		$text .= "<div>Focus Room: ".$fr_slots."</div>";			
		$text .= "<div>Wisdom Room: ".$wr_slots."</div>";
		$text .= "<div>Harmony Room: ".$vr_slots."</div>";
		$text .= "<div>Spirit Room: ".$sr_slots."</div>";						
//		$text .= "<div>Total: ".$slots_sum."</div>";
		$jsondata = array("text" => $text);
		echo $this->getJSON($jsondata);
		return;		
	}
	
	function getCalRoomSlots($room, $year, $month){			 
		$date_epoch = date('Y-m-d', mktime(0,0,0,$month,1,$year )); 
		$date_epoch_timestamp = mktime(0,0,0,$month,1,$year );
		$next_month_start = date('Y-m-d', strtotime('+1 months', $date_epoch_timestamp));//current +1 month	
		
		$slots = 0;
		$date = $date_epoch;
		while($date < $next_month_start){
			$day_avail = $this->chkDayAvailabler($date, $room, '', false);		
			$day_slots = 0;
			if($day_avail["slot_am"] =="booked") $day_slots+=1;
			if($day_avail["slot_pm"] =="booked") $day_slots+=1;			
			if($day_avail["slot_ev"] =="booked") $day_slots+=1;			
			$date = date('Y-m-d', strtotime('+1 days', strtotime($date)));//current +1 month	
			$slots += $day_slots;
		}
		return $slots;
	}	
	
	function getCalRoomSlots2($current_room, $year, $month){
		$param["release"] = self::$release; 		
		$c =& csmbolGlobalConf::Instance($param);	
		
		$booking_default_cal_user = $c->booking_cal_info[$current_room]["cal_user"];
		$booking_default_cal_magicCookie = $c->booking_cal_info[$current_room]["cal_mc"];		
		$booking_pending_cal_user  = $c->booking_cal_info[$current_room]["cal_pending_user"];			
		$cal_default_uri  = $c->booking_cal_info[$current_room]["cal_uri"];
		$cal_pending_uri = $c->booking_cal_info[$current_room]["cal_pending_uri"];
				
		date_default_timezone_set('Asia/Singapore');
		$date_epoch = date('Y-m-d', mktime(0,0,0,$month,1,$year ));
		$next_month_start = date('Y-m-d', strtotime('+1 months', strtotime($date_epoch)));
		$current_month_end = date('Y-m-d', strtotime('-1 days', strtotime($next_month_start)));
		$date1 = $date_epoch;
		$date2 = date('Y-m-d', strtotime('+10 days', strtotime($date_epoch)));

		$text = "";$slots = 0;
		for($i=0;$i<3;$i++){
			
			$gcal = $this->getGcal('read');	
			$query = $gcal->newEventQuery();
			$query->setUser($booking_default_cal_user);
			$query->setVisibility('private-'.$booking_default_cal_magicCookie);
			$query->setProjection('full');
			$query->setStartMin($date1);
			$query->setStartMax($date2);
			$query->setOrderby('starttime');
				
			try {
				$eventfeed = $gcal->getCalendarEventFeed($query);
				
				foreach($eventfeed as $event){
					$when = $event->getWhen();
					if($when){ //not <gd:recurrence> events
					
//						$ep = $event->getExtendedProperty();
//						if($ep){
//							$flag_slot = $ep[1]->getValue();/*array index issue 0->1 */
//						}else{
							$flag_slot = $this->decideSlotFlag($when[0]->getStartTime(),$when[0]->getEndTime());					
//						}
						
						$day_slots = 0;
						switch ($flag_slot){
							case "slot_am":
							case "slot_pm":						
							case "slot_ev":
								$day_slots+=1;				
								break;
							case "slot_fd1":
							case "slot_fd2":
								$day_slots+=2;
								break;
							case "slot_cd":
								$day_slots+=3;
								break;
							default:
								$day_slots+=1;
						}							
						$slots += $day_slots;
						$text .="<div>".$flag_slot."#".$slots."#".$when[0]->getStartTime().$when[0]->getEndTime()."#".$event->title->text."</div>";	
					}else{
						//do sth for recurrence events
					}
				}
			} catch (Zend_Gdata_App_Exception $e) {
				echo "Error: " . $e->getMessage();
			}	
			$date1 = $date2;
			$date2 = date('Y-m-d', strtotime('+10 days', strtotime($date1)));
			if(($i==1)&&($date2 < $next_month_start))
			$date2 = date('Y-m-d', strtotime('+11 days', strtotime($date1)));					
		}
		return $text;//$slots;			
	}
	
	function impCalProgress(){
		$pos = JRequest::getVar('pos');			
		
		$session = JFactory::getSession();	
		$cal_user_src = $session->get('cal_user_src');		
		$cal_user_des = $session->get('cal_user_des');	
		$date_start =  JRequest::getVar('date_start');	//$session->get('date_start');

/*		$jsondata = array("cal_user_src" =>$cal_user_src,"cal_user_des" =>$cal_user_des);
		echo $this->getJSON($jsondata);
		return;			
*/				
		$gcal_src = $this->getGcal();//full access
		$query_src = $gcal_src->newEventQuery();
		$query_src->setUser($cal_user_src); //
		$query_src->setVisibility('private');//not using magicCookie, so we can use full-access
		$query_src->setProjection('full');
		$query_src->setOrderby('starttime');

		$gcal_des = $this->getGcal();//full access		
		$query_des = $gcal_des->newEventQuery();		
		$query_des->setUser($cal_user_des); //
		$query_des->setVisibility('private');//not using magicCookie, so we can use full-access		
		$query_des->setProjection('full');

		$date1 = $date_start;
		$cal_des_uri = "http://www.google.com/calendar/feeds/".$cal_user_des."/private/full";
		$index = 0;$titles = array();$title[$index]=""; $start_time = array();$start_time[$index]=""; $end_time = array(); $end_time[$index]="";
		for($week=0;$week<4;$week++){
			$date2 = date('Y-m-d', strtotime('+1 weeks', strtotime($date1) ));
//			$date2 = date('Y-m-d', strtotime('+1 days', strtotime($date1)));	
			
			$query_src->setStartMin($date1);
			$query_src->setStartMax($date2);

			$query_des->setStartMin($date1);
			$query_des->setStartMax($date2);

			try {
				$eventfeed_des = $gcal_des->getCalendarEventFeed($query_des);
				foreach($eventfeed_des as $event_des){
					$event_des->delete();
				}				
			} catch (Zend_Gdata_App_Exception $e) {
				echo "Error: " . $e->getMessage();
			}
			try {
				$eventfeed_src = $gcal_src->getCalendarEventFeed($query_src);
				foreach($eventfeed_src as $event_src){

					$when_src = $event_src->getWhen();
					if($when_src){ //not <gd:recurrence> events
					
						if($event_src->title->text != $title[$index]||($when_src[0]->getStartTime()!=$start_time[$index])||($when_src[0]->getEndTime()!=$end_time[$index]))
						{//a new event
							//$index++;
							$start_time[$index] = $when_src[0]->getStartTime(); $end_time[$index] =  $when_src[0]->getEndTime(); $title[$index] = $event_src->title->text;
							
							$event_des = $gcal_des->newEventEntry();        
							$event_des->content = $gcal_des->newContent($event_src->content->text);       					
							$when = $gcal_des->newWhen();
							$when->startTime = $when_src[0]->getStartTime();
							$when->endTime = $when_src[0]->getEndTime();
							$event_des->when = array($when);  

							$ep = $event_src->getExtendedProperty();
							if($ep){
								$flag_slot = $ep[0]->getValue();
								$flag_bs = $ep[1]->getValue();
								$flag_bpt = $ep[2]->getValue();
								$flag_bpcid = $ep[3]->getValue();
								$flag_amt = $ep[4]->getValue(); 						
								$flag_bid = $ep[5]->getValue(); 							
							}else{
								$flag_slot = $this->decideSlotFlag($when->startTime,$when->endTime);					
								$flag_bs = "imported";
								$flag_bpt = "imported";
								$flag_bpcid = "imported";
								$flag_amt = "imported";
								$flag_bid = "imported";					
							}
							$slot_warning = ""; if($slot_flag == "unsolved") $slot_warning = "*!";		
							$event_des->title = $gcal_des->newTitle($slot_warning.$event_src->title->text);				
							$csmbolinfo = array();
							$csmbolinfo = $this->genCsmbolTag($flag_slot,$flag_bs,$flag_bpt,$flag_bpcid,$flag_amt,$flag_bid);																			
							$event_des->setExtendedProperty($csmbolinfo);					 	
					
							$gcal_des->insertEvent($event_des, $cal_des_uri);
						}
					}else{
						//do sth for recurrence events
					}
				}
			} catch (Zend_Gdata_App_Exception $e) {
				echo "Error: " . $e->getMessage();
			}			
			$date1 = $date2;			
		}
		$session = JFactory::getSession();
		$session->set('date_start', $date2);
		
		$jsondata = array("ok" => "ok", "date_start"=>$date2, "date2"=>$date2);
		echo $this->getJSON($jsondata);
		return;							
	}
	function clearCalProgress(){
		$pos = JRequest::getVar('pos');			
		
		$session = JFactory::getSession();	
		$cal_user_des = $session->get('cal_user_des');	
		$date_start =  $session->get('date_start');

/*		$jsondata = array("cal_user_src" =>$cal_user_src,"cal_user_des" =>$cal_user_des);
		echo $this->getJSON($jsondata);
		return;			
*/				
		$gcal_des = $this->getGcal();//full access				
		$query_des = $gcal_des->newEventQuery();		
		$query_des->setUser($cal_user_des); //
		$query_des->setVisibility('private');//not using magicCookie, so we can use full-access		
		$query_des->setProjection('full');		

		$date1 = $date_start;
		$cal_des_uri = "http://www.google.com/calendar/feeds/".$cal_usr_des."/private/full";
		$titles = array();
		for($week=0;$week<4;$week++){
			$date2 = date('Y-m-d', strtotime('+1 weeks', strtotime($date1) ));

			$query_des->setStartMin($date1);
			$query_des->setStartMax($date2);
			try {
				$eventfeed_des = $gcal_des->getCalendarEventFeed($query_des);
				foreach($eventfeed_des as $event_des){
					$event_des->delete();
				}				
			} catch (Zend_Gdata_App_Exception $e) {
				echo "Error: " . $e->getMessage();
			}
			$date1 = $date2;			
		}
		$session->set('date_start', $date2);
		
		$jsondata = array("ok" => "ok");
		echo $this->getJSON($jsondata);
		return;							
	}
	function genCsmbolTag($pflag_slot,$pflag_bs,$pflag_bpt,$pflag_bpcid,$pflag_amt,$pflag_bid){
		$csmbolinfo = array();
		//Name/Value pair must be both set, otherwise the flag will not store as extended property
		$flag_slot = new Zend_Gdata_Extension_ExtendedProperty();		
		$flag_slot->setName('flag_slot');
		$flag_slot->setValue($pflag_slot);$csmbolinfo[] = $flag_slot;
		$flag_bs = new Zend_Gdata_Extension_ExtendedProperty();	
		$flag_bs->setName('flag_booking_status');
		$flag_bs->setValue($pflag_bs);$csmbolinfo[] = $flag_bs;		
		$flag_bpt = new Zend_Gdata_Extension_ExtendedProperty();	
		$flag_bpt->setName('flag_bpt');
		$flag_bpt->setValue($pflag_bpt);$csmbolinfo[] = $flag_bpt;	
		$flag_bpcid = new Zend_Gdata_Extension_ExtendedProperty();	
		$flag_bpcid->setName('flag_bpcid');
		$flag_bpcid->setValue($pflag_bpcid);$csmbolinfo[] = $flag_bpcid;	
		$flag_amt = new Zend_Gdata_Extension_ExtendedProperty();	
		$flag_amt->setName('flag_amt');								
		$flag_amt->setValue($pflag_amt);$csmbolinfo[] = $flag_amt;	
		$flag_bid = new Zend_Gdata_Extension_ExtendedProperty();	
		$flag_bid->setName('flag_bid');
		$flag_bid->setValue($pflag_bid);$csmbolinfo[] = $flag_bid;		
		
		return $csmbolinfo;	
	}
	function decideSlotFlag($startTime, $endTime){
		date_default_timezone_set('Asia/Singapore');		
		$startTimestamp = strtotime($startTime);
		$endTimestamp = strtotime($endTime);
		$start_arr = getdate($startTimestamp);
		$end_arr = getdate($endTimestamp);
		$year = $start_arr['year'];
		$month = $start_arr['mon'];
		$day = $start_arr['mday'];
		
		$am_stamp1 = mktime(12,0,0,$month,$day,$year);
		$am_stamp2 = mktime(13,00,0,$month,$day,$year);		
		$pm_stamp1 = mktime(12,30,0,$month,$day,$year);
		$pm_stamp2 = mktime(13,00,0,$month,$day,$year);
		$pm_stamp3 = mktime(17,30,0,$month,$day,$year);
		$pm_stamp4 = mktime(19,00,0,$month,$day,$year);				
		$ev_stamp1 = mktime(19,00,0,$month,$day,$year);		
		$ev_stamp2 = mktime(21,30,0,$month,$day,$year);			

		$slot_flag = "unsolved";
		$slot_am = false;
		$slot_pm = false;
		$slot_ev = false;
		$slot_fd1 = false;
		$slot_fd2 = false;
		$slot_cd = false;
		
		if(($startTimestamp<$am_stamp1)||($endTimestamp<=$am_stamp2)) {$slot_am = true; $slot_flag = "slot_am";}	
		if($endTimestamp>$ev_stamp1) {$slot_ev = true; $slot_flag = "slot_ev";}
		if((($startTimestamp>=$pm_stamp1)&&($startTimestamp<$pm_stamp3))||(($endTimestamp>$pm_stamp2)&&($endTimestamp<=$pm_stamp4))||(($startTimestamp<=$pm_stamp1)&&($endTimestamp>=$pm_stamp4))) {$slot_pm = true; $slot_flag = "slot_pm";}
		if($slot_am&&$slot_pm&&!$slot_ev) {$slot_fd1 = true; $slot_flag = "slot_fd1";}
		if(!$slot_am&&$slot_pm&&$slot_ev) {$slot_fd2 = true; $slot_flag = "slot_fd2";}
		if($slot_am&&$slot_ev) {$slot_cd = true; $slot_flag = "slot_cd";}
		
/*		$jsondata = array("startTime" => $startTime,"endTime"=>$endTime,"year"=>$year,"month"=>$month,"day"=>$day,"startTimestamp"=>$startTimestamp );
		echo $this->getJSON($jsondata);
		return;
*/		return $slot_flag;
	}
	function selRoom(){
		$current_room = JRequest::getVar('current_room');		
		//get booking rates		
		$rates = $this->getRates($current_room);//get booking rates array(associative);
		
		$jsondata = array("room"=>$current_room,"room_rates" => $rates[$current_room]);
		echo $this->getJSON($jsondata);
		return;		
	}
}